﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using HitachiLib.Utils;
using HitachiLib.Data;
using HitachiLib.HitachiServiceRef;

namespace HitachiApp.Model.Resources
{
    public class ResourceManageViewModel : INotifyPropertyChanged
    {
        private ObservableCollection<ResourceManageItem> root_items = new ObservableCollection<ResourceManageItem>();
        private ResourceManageItem current_selected;
        private ResourceManageItem current_selected_help;
        private bool loaded = false;
        private Resource current_login;

        public bool Loaded
        {
            get { return loaded; }
        }
        public ObservableCollection<ResourceManageItem> RootResources
        {
            get { return root_items; }
            set { root_items = value; }
        }
        public ResourceManageItem CurrentSelected
        {
            get { return current_selected; }
            set { current_selected = value; RaisePropertyChanged("CurrentSelected"); }
        }
        public ResourceManageItem CurrentSelectedHelp
        {
            get { return current_selected_help; }
            set { current_selected_help = value; }
        }

        public void Load(Resource resource)
        {
            if (resource != null)
                current_login = resource;
            else
                resource = current_login;
            HitachiServiceClient client = WCFClient.GetClient();
            client.GetWholeManageDataByResourceIdCompleted +=
                new EventHandler<GetWholeManageDataByResourceIdCompletedEventArgs>(client_GetWholeManageDataByResourceIdCompleted);
            WCFClient.Retain();
            client.GetWholeManageDataByResourceIdAsync(resource.Data.ID);
        }

        public void LoadWholeManageData(WholeManageData data)
        {
            List<ResourceManageItem> all = new List<ResourceManageItem>();
            foreach (ResourceData pd in data.Resources)
            {
                ResourceManageItem pi = new ResourceManageItem();
                pi.Data = Resource.GetUnique(pd);
                all.Add(pi);
            }
            root_items.Clear();
            LinkResources(all);
            loaded = true;
            RaisePropertyChanged("RootProjects");
            RaisePropertyChanged("Loaded");
        }

        private void client_GetWholeManageDataByResourceIdCompleted(object sender, GetWholeManageDataByResourceIdCompletedEventArgs e)
        {
            WCFClient.Release();
            WholeManageData data = e.Result;
            LoadWholeManageData(data);
        }

        public void UpdateCurrentSelected()
        {
            if (current_selected != null)
            {
                HitachiServiceClient client = WCFClient.GetClient();
                client.UpdateResourceCompleted +=
                    new EventHandler<UpdateResourceCompletedEventArgs>(client_UpdateResourceCompleted);
                WCFClient.Retain();
                client.UpdateResourceAsync(current_selected.Data.Data);
            }
            RaisePropertyChanged("RootProjects");
        }

        private void client_UpdateResourceCompleted(object sender, UpdateResourceCompletedEventArgs e)
        {
            WCFClient.Release();
            if (!e.Result)
            {
                System.Windows.Browser.HtmlPage.Window.Alert("更新失败");
            }
        }

        public void MoveResourceItem(ResourceManageItem project, ResourceManageItem new_parent)
        {
            ResourceManageItem old_parent = project.Parent;
            if (old_parent != null)
            {
                old_parent.Children.Remove(project);
                new_parent.Children.Add(project);
                project.Parent = new_parent;
                MoveResource(project.Data, new_parent.Data);
            }
        }

        private void MoveResource(Resource resource, Resource new_parent)
        {
            Resource old_parent = resource.Parent;
            old_parent.Children.Remove(resource.Id);
            new_parent.AddChild(resource);
            resource.Data.ParentID = new_parent.Id;
            resource.Parent = new_parent;
        }

        private void LinkResources(List<ResourceManageItem> project_items)
        {
            Dictionary<int, ResourceManageItem> m = new Dictionary<int, ResourceManageItem>();
            Dictionary<int, ResourceManageItem> added = new Dictionary<int, ResourceManageItem>();
            root_items.Clear();
            foreach (ResourceManageItem pmi in project_items)
            {
                m.Add(pmi.Data.Id, pmi);
            }
            foreach (ResourceManageItem pmi in project_items)
            {
                AddPrjectWithParent(m, added, pmi);
            }
        }

        private void AddPrjectWithParent(Dictionary<int, ResourceManageItem> all, Dictionary<int, ResourceManageItem> added, ResourceManageItem pmi)
        {
            if (added.ContainsKey(pmi.Data.Id))
                return;
            if (!all.ContainsKey(pmi.Data.Data.ParentID))
            {
                root_items.Add(pmi);
            }
            else
            {
                ResourceManageItem parent = all[pmi.Data.Data.ParentID];
                pmi.Parent = parent;
                if (!parent.Children.Contains(pmi))
                    parent.Children.Add(pmi);
                AddPrjectWithParent(all, added, parent);
            }
            added.Add(pmi.Data.Id, pmi);
        }

        #region PropertChanged Block
        public event PropertyChangedEventHandler PropertyChanged;

        private void RaisePropertyChanged(string property)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(property));
            }
        }
        #endregion
    }
}
